import tkinter as tk
import random
import time

class Tetris:
    def __init__(self, master):
        self.master = master
        self.master.title("俄罗斯方块")
        self.master.resizable(False, False)
        
        # 游戏设置
        self.width = 10
        self.height = 20
        self.block_size = 30
        self.colors = ["white", "cyan", "yellow", "purple", "green", "red", "blue", "orange"]
        
        # 游戏状态
        self.board = [[0 for _ in range(self.width)] for _ in range(self.height)]
        self.current_piece = None
        self.current_pos = {"row": 0, "col": 0}
        self.game_over = False
        self.paused = False
        self.score = 0
        self.level = 1
        self.speed = 1000  # 初始下落速度(毫秒)
        
        # 创建UI
        self.create_ui()
        
        # 初始化游戏
        self.new_game()
    
    def create_ui(self):
        # 创建主框架
        main_frame = tk.Frame(self.master)
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 创建游戏画布
        self.canvas = tk.Canvas(
            main_frame, 
            width=self.width * self.block_size, 
            height=self.height * self.block_size,
            bg="black",
            highlightthickness=0
        )
        self.canvas.pack(side=tk.LEFT, padx=10, pady=10)
        
        # 创建信息面板
        info_frame = tk.Frame(main_frame)
        info_frame.pack(side=tk.RIGHT, fill=tk.Y, padx=10, pady=10)
        
        # 分数显示
        score_label = tk.Label(info_frame, text="分数:", font=("Arial", 16))
        score_label.pack(anchor=tk.W)
        self.score_var = tk.StringVar(value="0")
        self.score_display = tk.Label(info_frame, textvariable=self.score_var, font=("Arial", 24, "bold"))
        self.score_display.pack(anchor=tk.W, pady=(0, 20))
        
        # 等级显示
        level_label = tk.Label(info_frame, text="等级:", font=("Arial", 16))
        level_label.pack(anchor=tk.W)
        self.level_var = tk.StringVar(value="1")
        self.level_display = tk.Label(info_frame, textvariable=self.level_var, font=("Arial", 24, "bold"))
        self.level_display.pack(anchor=tk.W, pady=(0, 20))
        
        # 下一个方块预览
        next_label = tk.Label(info_frame, text="下一个:", font=("Arial", 16))
        next_label.pack(anchor=tk.W)
        self.next_canvas = tk.Canvas(
            info_frame,
            width=4 * self.block_size,
            height=4 * self.block_size,
            bg="black",
            highlightthickness=0
        )
        self.next_canvas.pack(anchor=tk.W, pady=(0, 20))
        
        # 控制按钮
        control_frame = tk.Frame(info_frame)
        control_frame.pack(side=tk.BOTTOM, fill=tk.X)
        
        self.start_button = tk.Button(control_frame, text="开始", command=self.new_game)
        self.start_button.pack(side=tk.LEFT, padx=5)
        
        self.pause_button = tk.Button(control_frame, text="暂停", command=self.toggle_pause)
        self.pause_button.pack(side=tk.LEFT, padx=5)
        
        self.quit_button = tk.Button(control_frame, text="退出", command=self.master.quit)
        self.quit_button.pack(side=tk.LEFT, padx=5)
        
        # 绑定键盘事件
        self.master.bind("<Left>", lambda event: self.move(-1, 0))
        self.master.bind("<Right>", lambda event: self.move(1, 0))
        self.master.bind("<Down>", lambda event: self.move(0, 1))
        self.master.bind("<Up>", lambda event: self.rotate())
        self.master.bind("<space>", lambda event: self.hard_drop())
        self.master.bind("p", lambda event: self.toggle_pause())
    
    def new_game(self):
        # 重置游戏状态
        self.board = [[0 for _ in range(self.width)] for _ in range(self.height)]
        self.current_piece = self.get_new_piece()
        self.next_piece = self.get_new_piece()
        self.current_pos = {"row": 0, "col": self.width // 2 - 2}
        self.game_over = False
        self.paused = False
        self.score = 0
        self.level = 1
        self.speed = 1000
        self.score_var.set(str(self.score))
        self.level_var.set(str(self.level))
        
        # 清空画布
        self.canvas.delete("all")
        self.next_canvas.delete("all")
        
        # 绘制游戏区域边框
        self.canvas.create_rectangle(
            0, 0, 
            self.width * self.block_size, 
            self.height * self.block_size,
            outline="white"
        )
        
        # 开始游戏循环
        self.update()
    
    def get_new_piece(self):
        # 7种俄罗斯方块形状
        shapes = [
            [[1, 5, 9, 13], [4, 5, 6, 7]],  # I
            [[1, 2, 5, 9], [0, 4, 5, 6], [1, 5, 9, 8], [4, 5, 6, 10]],  # J
            [[1, 2, 6, 10], [5, 6, 7, 9], [2, 6, 10, 11], [3, 5, 6, 7]],  # L
            [[1, 2, 5, 6]],  # O
            [[6, 7, 9, 10], [1, 5, 6, 10]],  # S
            [[1, 4, 5, 6], [1, 5, 6, 9], [4, 5, 6, 9], [1, 4, 5, 9]],  # T
            [[4, 5, 9, 10], [2, 6, 5, 9]]  # Z
        ]
        
        # 随机选择一种形状和颜色
        shape = random.choice(shapes)
        color = random.randint(1, 7)
        
        return {"shape": shape, "color": color, "rotation": 0}
    
    def draw_board(self):
        # 清空画布
        self.canvas.delete("all")
        
        # 绘制游戏区域边框
        self.canvas.create_rectangle(
            0, 0, 
            self.width * self.block_size, 
            self.height * self.block_size,
            outline="white"
        )
        
        # 绘制已落下的方块
        for row in range(self.height):
            for col in range(self.width):
                if self.board[row][col] != 0:
                    color = self.colors[self.board[row][col]]
                    self.canvas.create_rectangle(
                        col * self.block_size, 
                        row * self.block_size, 
                        (col + 1) * self.block_size, 
                        (row + 1) * self.block_size,
                        fill=color,
                        outline="black"
                    )
        
        # 绘制当前方块
        if self.current_piece:
            shape = self.current_piece["shape"][self.current_piece["rotation"]]
            color = self.colors[self.current_piece["color"]]
            
            for i in range(4):
                row = self.current_pos["row"] + (shape[i] // 4)
                col = self.current_pos["col"] + (shape[i] % 4)
                
                if 0 <= row < self.height and 0 <= col < self.width:
                    self.canvas.create_rectangle(
                        col * self.block_size, 
                        row * self.block_size, 
                        (col + 1) * self.block_size, 
                        (row + 1) * self.block_size,
                        fill=color,
                        outline="black"
                    )
        
        # 如果游戏结束，显示游戏结束信息
        if self.game_over:
            self.canvas.create_rectangle(
                self.width * self.block_size // 4,
                self.height * self.block_size // 3,
                self.width * self.block_size * 3 // 4,
                self.height * self.block_size * 2 // 3,
                fill="black",
                outline="white"
            )
            self.canvas.create_text(
                self.width * self.block_size // 2,
                self.height * self.block_size // 2 - 20,
                text="游戏结束",
                fill="white",
                font=("Arial", 24, "bold")
            )
            self.canvas.create_text(
                self.width * self.block_size // 2,
                self.height * self.block_size // 2 + 20,
                text=f"得分: {self.score}",
                fill="white",
                font=("Arial", 16)
            )
        
        # 如果游戏暂停，显示暂停信息
        if self.paused:
            self.canvas.create_rectangle(
                self.width * self.block_size // 4,
                self.height * self.block_size // 3,
                self.width * self.block_size * 3 // 4,
                self.height * self.block_size * 2 // 3,
                fill="black",
                outline="white"
            )
            self.canvas.create_text(
                self.width * self.block_size // 2,
                self.height * self.block_size // 2,
                text="游戏暂停",
                fill="white",
                font=("Arial", 24, "bold")
            )
    
    def draw_next_piece(self):
        # 清空预览画布
        self.next_canvas.delete("all")
        
        # 绘制下一个方块
        if self.next_piece:
            shape = self.next_piece["shape"][self.next_piece["rotation"]]
            color = self.colors[self.next_piece["color"]]
            
            # 计算居中位置
            min_col = min(shape[i] % 4 for i in range(4))
            max_col = max(shape[i] % 4 for i in range(4))
            min_row = min(shape[i] // 4 for i in range(4))
            max_row = max(shape[i] // 4 for i in range(4))
            
            offset_x = (4 - (max_col - min_col + 1)) // 2 - min_col
            offset_y = (4 - (max_row - min_row + 1)) // 2 - min_row
            
            for i in range(4):
                row = (shape[i] // 4) + offset_y
                col = (shape[i] % 4) + offset_x
                
                self.next_canvas.create_rectangle(
                    col * self.block_size, 
                    row * self.block_size, 
                    (col + 1) * self.block_size, 
                    (row + 1) * self.block_size,
                    fill=color,
                    outline="black"
                )
    
    def valid_position(self, piece=None, pos=None):
        if piece is None:
            piece = self.current_piece
        if pos is None:
            pos = self.current_pos
        
        shape = piece["shape"][piece["rotation"]]
        
        for i in range(4):
            row = pos["row"] + (shape[i] // 4)
            col = pos["col"] + (shape[i] % 4)
            
            # 检查是否超出边界或与已有方块重叠
            if row >= self.height or col < 0 or col >= self.width:
                return False
            if row >= 0 and self.board[row][col] != 0:
                return False
        
        return True
    
    def merge_piece(self):
        shape = self.current_piece["shape"][self.current_piece["rotation"]]
        color = self.current_piece["color"]
        
        for i in range(4):
            row = self.current_pos["row"] + (shape[i] // 4)
            col = self.current_pos["col"] + (shape[i] % 4)
            
            if row >= 0:
                self.board[row][col] = color
    
    def clear_lines(self):
        lines_cleared = 0
        
        for row in range(self.height - 1, -1, -1):
            if all(self.board[row]):
                # 移除当前行
                del self.board[row]
                # 在顶部添加一个新的空行
                self.board.insert(0, [0 for _ in range(self.width)])
                lines_cleared += 1
        
        # 计算得分 (经典俄罗斯方块计分规则)
        if lines_cleared == 1:
            self.score += 100 * self.level
        elif lines_cleared == 2:
            self.score += 300 * self.level
        elif lines_cleared == 3:
            self.score += 500 * self.level
        elif lines_cleared >= 4:
            self.score += 800 * self.level
        
        # 更新分数显示
        self.score_var.set(str(self.score))
        
        # 更新等级 (每得1000分升一级)
        new_level = max(1, self.score // 1000 + 1)
        if new_level != self.level:
            self.level = new_level
            self.level_var.set(str(self.level))
            # 调整下落速度
            self.speed = max(100, 1000 - (self.level - 1) * 100)
    
    def move(self, dx, dy):
        if self.game_over or self.paused:
            return
        
        new_pos = {"row": self.current_pos["row"] + dy, "col": self.current_pos["col"] + dx}
        
        if self.valid_position(pos=new_pos):
            self.current_pos = new_pos
            self.draw_board()
            return True
        elif dy > 0:
            # 如果是向下移动但不能移动，则合并方块
            self.merge_piece()
            self.clear_lines()
            self.current_piece = self.next_piece
            self.next_piece = self.get_new_piece()
            self.current_pos = {"row": 0, "col": self.width // 2 - 2}
            
            # 检查游戏是否结束
            if not self.valid_position():
                self.game_over = True
            
            self.draw_board()
            self.draw_next_piece()
            return False
        
        return False
    
    def rotate(self):
        if self.game_over or self.paused:
            return
        
        new_rotation = (self.current_piece["rotation"] + 1) % len(self.current_piece["shape"])
        new_piece = {
            "shape": self.current_piece["shape"],
            "color": self.current_piece["color"],
            "rotation": new_rotation
        }
        
        # 尝试旋转 (经典俄罗斯方块的墙踢机制)
        if self.valid_position(piece=new_piece):
            self.current_piece = new_piece
            self.draw_board()
        else:
            # 尝试墙踢 (左右移动)
            for dx in [-1, 1, -2, 2]:
                new_pos = {"row": self.current_pos["row"], "col": self.current_pos["col"] + dx}
                if self.valid_position(piece=new_piece, pos=new_pos):
                    self.current_piece = new_piece
                    self.current_pos = new_pos
                    self.draw_board()
                    return
    
    def hard_drop(self):
        if self.game_over or self.paused:
            return
        
        # 快速下落到底部
        while self.move(0, 1):
            pass
    
    def toggle_pause(self):
        if self.game_over:
            return
        
        self.paused = not self.paused
        self.draw_board()
        
        if not self.paused:
            # 恢复游戏循环
            self.update()
    
    def update(self):
        if not self.game_over and not self.paused:
            # 自动下落
            self.move(0, 1)
            
            # 继续游戏循环
            self.master.after(self.speed, self.update)

if __name__ == "__main__":
    root = tk.Tk()
    game = Tetris(root)
    root.mainloop()